#include "stdafx.h"
#include "..\headers\VisualComponents.h"
#include "..\headers\GameObject.h"
#include "..\headers\GameTime.h"

namespace ne{

MeshComponent::MeshComponent(void):
m_sceneManager(nullptr),
m_entity(nullptr),
m_sceneNode(nullptr) {m_type |= COMPONENT_MESH;}
MeshComponent::~MeshComponent(void){m_owner->Notify(&CEvent(NE_MSG_MESH_COMPONENT_DESTROYED));}

void MeshComponent::Init(){
	m_sceneManager=GameObject::GetSceneManager();
	m_sceneNode=m_owner->GetSceneNode()->createChildSceneNode();
	m_owner->Register(this);
}

void MeshComponent::LoadMesh(const char* filename){
	if (m_entity != nullptr){
		m_sceneNode->detachObject(m_entity);
		m_sceneManager->destroyEntity(m_entity);
	}
	m_entity = m_sceneManager->createEntity(filename);
	m_sceneNode->attachObject(m_entity);
}

void MeshComponent::SetMaterial(const char* material){
	if (m_entity!=nullptr){
		m_entity->setMaterialName(material);
	}
}

void MeshComponent::CreatePlane(const char* name,float width,float height,int xsegments,int ysegments){
	if (m_entity != nullptr){
		m_sceneNode->detachObject(m_entity);
		m_sceneManager->destroyEntity(m_entity);
	}
	Ogre::Plane plane(Ogre::Vector3::UNIT_Y,0);
	Ogre::MeshManager::getSingleton().createPlane(name,Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,plane,width,height,xsegments,ysegments,true,1,5,5,Ogre::Vector3::UNIT_Z);
	m_entity = m_sceneManager->createEntity(name);
	m_sceneNode->attachObject(m_entity);
}

void MeshComponent::SetScale(float x,float y,float z){m_sceneNode->setScale(x,y,z);}
void MeshComponent::SetScale(const Ogre::Vector3& scale){m_sceneNode->setScale(scale);}

void MeshComponent::DestroyPlane(const char* name){
	Ogre::MeshManager::getSingleton().remove(name);
}

void MeshComponent::Shut(){
	if (m_entity){
		m_sceneNode->detachObject(m_entity);
		m_sceneManager->destroyEntity(m_entity);
		m_sceneManager->destroySceneNode(m_sceneNode);
		m_entity = nullptr;
	}
	m_owner->Unregister(this);
}

bool MeshComponent::IsVisible(){return m_entity->isVisible();}
void MeshComponent::SetVisible(bool value){m_entity->setVisible(value);}
void MeshComponent::SetSkeletonBlendMode(int p_blendMode){
	if(m_entity){m_entity->getSkeleton()->setBlendMode((Ogre::SkeletonAnimationBlendMode)p_blendMode);}
}

void MeshComponent::Notify(CEvent* evt){
	switch (evt->m_type){
	case NE_MSG_GET_OGRE_ENTITY:
		{
			*static_cast<CEventEntity*>(evt)->m_entity=m_entity;
			break;
		}
	default:
		break;
	}
}

AnimationComponent::AnimationComponent():
m_animationState(nullptr),
m_entity(nullptr),
m_isPlaying(false){m_type |= COMPONENT_ANIMATION;}
AnimationComponent::~AnimationComponent(){}

void AnimationComponent::Update(GameTime* gameTime){
	if(m_isPlaying&&m_animationState){
		m_animationState->addTime(gameTime->DeltaTime());
	}
}

void AnimationComponent::StopAnimation(){
	if(m_animationState){
		m_animationState->setTimePosition(Ogre::Real(0));
		m_animationState->setEnabled(false);
	}
}

void AnimationComponent::PlayAnimation(const char* p_animId){
	m_isPlaying=true;
	GetOgreEntity();
	if(m_entity){
		if(m_animationState){m_animationState->setTimePosition(0);m_animationState->setEnabled(false);}
		m_animationState=m_entity->getAnimationState(p_animId);
		if(!m_animationState->getEnabled()){m_animationState->setEnabled(true);m_animationState->setLoop(true);}
	}
	else{
		System::Log("Warning: Could not get Ogre::Entity* in AnimationComponent when trying to play animation");
	}
}

void AnimationComponent::Notify(CEvent* evt){
	switch (evt->m_type){
	case NE_MSG_MESH_COMPONENT_DESTROYED:
		{
			m_animationState=nullptr;
			m_entity=nullptr;
			break;
		}
	default:
		break;
	}
}

void AnimationComponent::Init(){m_owner->Register(this);GetOgreEntity();}
void AnimationComponent::GetOgreEntity(){
	if(m_entity==nullptr){
		CEventEntity msg(NE_MSG_GET_OGRE_ENTITY,&m_entity);
		m_owner->Notify(&msg);	// if we don't have an entity from the mesh component we get it
	}
}

void AnimationComponent::Shut(){
	m_animationState=nullptr;
	m_entity=nullptr;
	m_owner->Unregister(this);
}

LightComponent::LightComponent():m_sceneManager(nullptr){m_type|=COMPONENT_LIGHT;}
LightComponent::~LightComponent(){}

void LightComponent::Init(){
	m_sceneManager=GameObject::GetSceneManager();
	m_light = m_sceneManager->createLight();
	m_sceneNode = m_owner->GetSceneNode()->createChildSceneNode();
	m_sceneNode->attachObject(m_light);
}

void LightComponent::Shut(){
	m_sceneNode->detachObject(m_light);
	m_sceneManager->destroyLight(m_light);
	m_sceneManager->destroySceneNode(m_sceneNode);
	m_sceneNode = nullptr;
	m_light = nullptr;
}

} // namespace ne